1. sync.Pool 的功用
sync.Pool通常被稱為,臨時對象池。
在頻繁地分配和回收內存,會給GC帶來一定的負擔。
sync.Pool可以將暫時不用的對象緩存起來,下次要需要使用的時候,可以直接使用。
Pool這名字可能會產生誤導,Pool裡裝的對象,會在沒有通知的情況下,被回收。用Cache來思考這個功能,會比較直觀。
2. sync.Pool類型,有兩個方法,Put和Get
A. Get方法,會從當前的池中刪除掉任何一個值,然後把這個值做為結果返回。
如果此時當前的池中沒有任何值,那麼這個方法就會使用當前池的New字段創建一個新值,並將值返回。
B. Put方法,會將臨時對象,儲存到池中。
3. 初始化臨時對象池
sync.Pool類型的New字段代表著創建臨時對象的函數。這個函數的類型是沒有參數但有唯一結果的函數類型。
func() interface{}
而這個New字段的函數,需要我們在初始化臨時對象池的時候就給定。
4. 程式碼範例
package main
import (
"fmt"
"sync"
)
func main() {
pool := &sync.Pool{
New: func() interface{} {
fmt.Println("Create a new object.")
return 10
},
}
pool.Put(100)
pool.Put(100)
pool.Put(100)
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
fmt.Println(pool.Get())
wg.Done()
}(i)
}
wg.Wait()
}
https://play.golang.org/p/zHZObADzCg9
說明:
將臨時對象100,存放三次,到臨時對象池中。
前三個goroutine,會從臨時對象池取得100。
之後的goroutine取不到值,就會呼叫New字段的函數。而New函數會回傳10。
參考來源:
郝林-Go语言核心36讲
https://github.com/hyper0x/Golang_Puzzlers
https://golang.org/pkg/cmd/go/internal/test/